﻿/*
 * @author: wizardc
 */

using System;
using System.Collections.Generic;

namespace Dou.Utils
{
    /// <summary>
    /// 对象池
    /// </summary>
    public class ObjectPool
    {
        private int _maxCount;
        private Func<object> _creator;
        private Stack<object> _stack;
        private Dictionary<object, bool> _map;

        public ObjectPool(Func<object> creator) : this(50, creator)
        {
        }

        public ObjectPool(int maxCount, Func<object> creator)
        {
            _maxCount = maxCount;
            _creator = creator;
            _stack = new Stack<object>();
            _map = new Dictionary<object, bool>();
        }

        public int size
        {
            get { return _stack.Count; }
        }

        public void Join(object obj)
        {
            if (obj is ICacheable)
            {
                ((ICacheable) obj).OnRecycle();
            }
#if UNITY_EDITOR
            if (_stack.Count >= _maxCount)
            {
                Log.Warning($"类型\"{obj.GetType().FullName}\"的对象池已满，最大数量为\"{_maxCount}\"");
            }
#endif
            if (_stack.Count < _maxCount)
            {
                if (!_map.ContainsKey(obj))
                {
                    _map.Add(obj, true);
                    _stack.Push(obj);
                }
            }
        }

        public object Take()
        {
            object obj;
            if (_stack.Count == 0)
            {
                obj = _creator();
            }
            else
            {
                obj = _stack.Pop();
                _map.Remove(obj);
                if (obj is ICacheable)
                {
                    ((ICacheable) obj).OnReuse();
                }
            }
            return obj;
        }

        public void Clear()
        {
            _stack.Clear();
            _map.Clear();
        }
    }
}
